/*
 * Galaxium Messenger
 * Copyright (C) 2008 Ben Motmans <ben.motmans@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Collections.Generic;

using Galaxium.Core;
using Anculus.Core;

namespace Galaxium.Protocol
{
	internal sealed class IndexedConversationLogMetaData
	{
		private IndexedConversationLog _log;
		
		private int _maximumLogSize;
		
		private string _indexFilename;
		private Stream _indexStream;

		private const int _magic = -0xabcd;
		private const int _version = 2;
		
		private List<IndexedConversationLogArchive> _archives;
		
		internal IndexedConversationLogMetaData (IndexedConversationLog log, string indexFilename)
		{
			_log = log;
			_indexFilename = indexFilename;

			_archives = log.Archives;
			
			ReadIndex ();
		}
		
		public int MaximumLogSize
		{
			get { return _maximumLogSize; }
		}
		
		public int MaximumArchiveSize
		{
			get { return _maximumLogSize / LogArchiveCount; }
		}
		
		public int LogArchiveCount
		{
			get { return ConversationLogUtility.GetLogChunkCount (_maximumLogSize); }
		}
		
		internal void ReadIndex ()
		{
			if (!File.Exists (_indexFilename)) {
				_maximumLogSize = ConversationLogUtility.MaximumLogSize;
				_log.DeleteLogArchives ("missing index");
				return;
			}
			
			_indexStream = new FileStream (_indexFilename, FileMode.Open, FileAccess.Read);
			using (_indexStream) {
				using (BinaryReader reader = new BinaryReader (_indexStream)) {
					int magic = reader.ReadInt32 ();
					if (magic != _magic) {
						_log.DeleteLogArchives ("incorrect magic number");
						return;
					}
					
					int version = reader.ReadInt32 ();
					if (version != _version) {
						_log.DeleteLogArchives ("unsupported version");
						return;
					}
					
					_maximumLogSize = reader.ReadInt32 ();
					int archiveCount = reader.ReadInt32 ();
					
					for (int i=0; i<archiveCount; i++)
						_archives.Add (new IndexedConversationLogArchive (_log, reader));
					
					Sort.QuickSort (_archives);
				}
			}
		}

		internal void WriteIndex ()
		{
			_indexStream = new FileStream (_indexFilename, FileMode.Create, FileAccess.Write);
			using (_indexStream) {
				using (BinaryWriter writer = new BinaryWriter (_indexStream)) {
					writer.Write (_magic);
					writer.Write (_version);
					
					writer.Write (_maximumLogSize);
					writer.Write (_archives.Count);

					for (int i=0; i<_archives.Count; i++) {
						IndexedConversationLogArchive archive = _archives[i];
						archive.ArchiveIndex = i;
						archive.WriteArchiveMetaData (archive, writer);
					}
				}
			}
		}
	}
}